use cmsis_rtos2_rs::{os_delay, Instant};
use utils::defer_ref;

use crate::cp_heat::{driver::{ctrl, sensor, APP_INFO}, steam_heat_task, HeatErr};

pub fn draw_water_with_v3(ml: u16) -> Result<(), HeatErr> {
    defer_ref!({
        ctrl::v3_close();
    });
    ctrl::v3_open();
    draw_with(ml as u32)
}

pub fn draw_water_with_v4(ml: u16) -> Result<(), HeatErr> {
    defer_ref!({
        ctrl::v4_close();
    });
    ctrl::v4_open();
    draw_with(ml as u32)
}

pub fn draw_steam_start() {
    steam_heat_task::ctrl(steam_heat_task::State::Inject);
}

pub fn draw_steam_stop() {
    steam_heat_task::ctrl(steam_heat_task::State::Release);
}

fn draw_with(ml: u32) -> Result<(), HeatErr> {
    let flow_arg = APP_INFO.lock().flow_1000l_puls_count as u32;
    if flow_arg == 0 {
        return Err(HeatErr::FlowArgInvalid);
    }
    defer_ref!({
        ctrl::water_pump_close();
    });
    ctrl::water_pump_open();
    sensor::flow_count_reset();
    let mut last_ins = Instant::new();
    let mut last_ml: u32 = 0;
    loop {
        let current_ml = sensor::flow_ml(flow_arg);
        if current_ml >= ml {
            break;
        }
        if last_ins.elapsed() >= 5000 {
            last_ins.reset();
            if last_ml.abs_diff(current_ml) < 5 {
                return Err(HeatErr::DrawFail);
            }
            last_ml = current_ml;
        }
        os_delay(100);
    }
    Ok(())
}









